package ar.edu.unrn.lia.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.inject.Named;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import ar.edu.unrn.lia.dao.AlquilerDAO;
import ar.edu.unrn.lia.generic.GenericDaoJpaImpl;
import ar.edu.unrn.lia.model.Alquiler;
import ar.edu.unrn.lia.model.CuotaPreIngreso;
import ar.edu.unrn.lia.model.Alquiler.AlquilerEstado;
import ar.edu.unrn.lia.model.AlquilerCuota;
import ar.edu.unrn.lia.model.AlquilerCuota.CoutaEstado;
import ar.edu.unrn.lia.util.FuncionesDate;

@Named("alquilerDAO")
public class AlquilerDAOImpl extends GenericDaoJpaImpl<Alquiler, Long>
		implements AlquilerDAO, Serializable {

	public List<AlquilerCuota> alquileresActivosCuotaPendientePorMes(int mes) {
		Query query = this.entityManager
				.createQuery(
						"select c from "
								+ AlquilerCuota.class.getName()
								+ " c "
								+ "where (c.estado = :estadoCuotaPE or c.estado = :estadoCuotaV) and "
								+ " MONTH(c.fecha) = :mes  and"
								+ " YEAR(c.fecha) = :anio  and"
								+ " c.alquiler.estado = :estadoAlquiler "
								+ " order by c.alquiler.propiedad.propietario.apellido ASC")
				.setParameter("estadoCuotaPE", CoutaEstado.PE)
				.setParameter("estadoCuotaV", CoutaEstado.V)
				.setParameter("estadoAlquiler", AlquilerEstado.ACTIVO)
				.setParameter("mes", mes)
				.setParameter("anio", FuncionesDate.anioHoy());

		return query.getResultList();
	}

	public List<Alquiler> alquileresPorVencer() {
		CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();

		CriteriaQuery<Alquiler> q = builder.createQuery(Alquiler.class);
		Root<Alquiler> c = q.from(Alquiler.class);
		q.select(c);
		Predicate[] predicatesList = new ArrayList<Predicate>()
				.toArray(new Predicate[2]);

		predicatesList[0] = builder.equal(c.get("estado"),
				AlquilerEstado.ACTIVO);

		ParameterExpression<Date> cr = builder.parameter(Date.class);

		predicatesList[1] = builder.between(cr,
				c.<Date> get("fechaProximaVencer"), c.<Date> get("fechaFin"));

		q.where(predicatesList);
		TypedQuery<Alquiler> query = this.entityManager.createQuery(q);
		query.setParameter(cr, new Date(), TemporalType.DATE);

		return query.getResultList();

	}

	// public List<Alquiler> alquileresPorVencer(Integer dias)
	// {
	// Query query = this.entityManager.createQuery("from " +
	// Alquiler.class.getName() +
	// " as a where :currentDate between a.fechaProximaVencer and a.fechaFin");
	// //query.setParameter("dias", dias);
	// query.setParameter("currentDate", new Date());
	// return query.getResultList();
	// }

	public Predicate[] getSearchPredicates(Root<Alquiler> root,
			Map<String, String> filters) {

		CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
		List<Predicate> predicatesList = new ArrayList<Predicate>();
		root.alias("entity");

		String direccion = filters.get("propiedad.direccion");
		if (direccion != null && !"".equals(direccion)) {
			predicatesList.add(builder.like(
					root.get("propiedad").<String> get("direccion"),
					'%' + direccion + '%'));
		}

		String inquilino = filters.get("inquilino.apellido");
		if (inquilino != null && !"".equals(inquilino)) {
			predicatesList.add(builder.like(
					root.get("inquilino").<String> get("apellido"),
					'%' + inquilino + '%'));
		}

		String propietario = filters.get("propiedad.propietario.apellido");
		if (propietario != null && !"".equals(propietario)) {
			predicatesList
					.add(builder.like(root.get("propiedad").get("propietario")
							.<String> get("apellido"), '%' + propietario + '%'));
		}
		
		String garante = filters.get("garante.apellido");
		if (garante != null && !"".equals(garante)) {
			predicatesList
					.add(builder.like(root.get("garante").<String> get("apellido"), '%' + garante + '%'));
		}

		String estado = filters.get("estado");
		if (estado != null && !"".equals(estado)) {
			for (AlquilerEstado av : AlquilerEstado.values()) {
				if (av.toString().equals(estado)) {
					predicatesList.add(builder.equal(root.get("estado"), av));
				}
			}
		}

		return predicatesList.toArray(new Predicate[predicatesList.size()]);
	}

}